import base64
import io
import os
import time
from PIL import Image
from selenium.common import TimeoutException, NoSuchElementException
from selenium.webdriver.support.wait import WebDriverWait
from config.settings import get_config
from base.base_page import BasePage
import ddddocr

"""
封装登录函数，根据传入的device_type，调用不同的登录参数（config.ini）

"""

class LoginPage(BasePage):
    def __init__(self, driver, device_type, logger=None):
        super().__init__(driver, device_type, logger=logger)  # 传递日志实例
        self.driver = driver
        self.config = get_config(device_type)  # 获取全局配置

    def login(self, username=None, password=None):
        """带验证码重试机制的登录流程"""
        max_retries = 20  # 最大重试次数
        attempt = 0  # 当前尝试次数

        while attempt < max_retries:
            try:
                if attempt == 0:
                    # 等待登录表单加载
                    self.wait_for_login_form()
                    # 输入凭证
                    self.input_credentials(username, password)
                # 处理验证码（每次重试都执行）
                if self.config.captcha_enabled:
                    # 获取验证码、清空、输入新验证码
                    self.process_captcha()
                # 提交登录
                self.submit_login()

                # 验证登录结果
                if self.verify_login_result():
                    return  # 登录成功，退出函数
                else:
                    attempt += 1
                    # 刷新验证码
                    time.sleep(1)
                    self.refresh_captcha_image()
                    self.logger.info(f"登录失败，正在进行第 {attempt} 次重试...")

            except Exception as e:
                # 提取干净的异常信息（取第一行）
                error_lines = str(e).split('\n')
                clean_error = error_lines[0].split("Alert Text: ")[-1].strip()
                self.logger.info(f"登录流程异常: {clean_error}")
                attempt += 1  # 增加尝试次数
                self.refresh_captcha_image()  # 刷新验证码
                self.logger.info(f"登录失败，正在进行第 {attempt} 次重试...")

        self.logger.error("达到最大重试次数，登录失败")
        return False

    def refresh_captcha_image(self):
        """刷新验证码图片"""
        captcha_img1 = self.capture_captcha()
        captcha_text1 = self.recognize_captcha(captcha_img1)
        time.sleep(1)
        self.click('login_page_module', "captcha_image")
        time.sleep(1)
        captcha_img2 = self.capture_captcha()
        captcha_text2 = self.recognize_captcha(captcha_img2)
        if captcha_text1 != captcha_text2:
            self.logger.info("刷新验证码成功")
            pass
        else:
            self.logger.error("刷新验证码失败")

    def input_credentials(self, username, password):
        """输入用户名密码"""
        if self.find_element('login_page_module', 'username'):
            self.input_text('login_page_module', 'username', username)
            self.soft_assert_input_value('login_page_module', 'username', username)
            self.input_text('login_page_module','password' , password)
            self.soft_assert_input_value('login_page_module', 'password', password)

    def process_captcha(self):
        """处理验证码流程"""
        # self.logger.info("开始验证码处理流程")
        for attempt in range(1, self.config.captcha_retry + 1):

            # 获取验证码图像
            captcha_img = self.capture_captcha()
            # 识别验证码
            captcha_text = self.recognize_captcha(captcha_img)
            # 输入验证码
            self.input_captcha(captcha_text)
            # 删除保存的图像
            os.remove("captcha.jpg")
            time.sleep(1)
            return  # 成功则退出循环

        raise RuntimeError(f"验证码处理超过最大重试次数 {self.config.captcha_retry}")

    def capture_captcha(self):
        try:
            captcha_element = self.find_element('login_page_module', 'captcha_image')
            captcha_url = captcha_element.get_attribute('src')
            self.logger.debug(f"验证码URL原始内容: {captcha_url}")  # 调试日志

            # 检查是否为Data URI格式
            if not captcha_url.startswith("data:image"):
                raise ValueError("验证码URL不是Data URI格式，可能是普通图片链接")

            # 安全分割base64数据
            parts = captcha_url.split(",", 1)
            if len(parts) < 2:
                raise ValueError("验证码URL格式错误，缺少base64数据部分")

            base64_str = parts[1]
            img_bytes = base64.b64decode(base64_str)

            # 图像处理
            image = Image.open(io.BytesIO(img_bytes))
            if image.mode != 'RGB':
                image = image.convert('RGB')

            # 保存验证码
            image.save("captcha.jpg")
            # self.logger.info("验证码已保存至captcha.jpg")
            return image

        except NoSuchElementException:
            self.logger.error("无法定位验证码元素")
            raise
        except (ValueError, IndexError) as ve:
            self.logger.error(f"验证码格式错误: {str(ve)}")
            raise
        except Exception as e:
            self.logger.error(f"验证码处理未知错误: {str(e)}", exc_info=True)
            raise

    def recognize_captcha(self, image):
        # 使用OCR识别文本
        # image.save("captcha.jpg")
        ocr = ddddocr.DdddOcr()
        # 切换为第二套OCR模型
        # ocr = ddddocr.DdddOcr(beta=True)
        with open("captcha.jpg", "rb") as f:
            image = f.read()
        text = ocr.classification(image)
        return text

    def input_captcha(self, text):
        """输入验证码"""
        self.input_text('login_page_module', 'captcha_input',text)

    def submit_login(self):
        """提交登录"""
        self.click('login_page_module', 'submit_button')
        self.logger.info("登录请求已提交")

    def verify_login_result(self):
        """验证登录结果"""
        try:
            WebDriverWait(self.driver, 2).until(
                lambda d: "/login" not in d.current_url,
                message="登录后页面跳转超时"
            )
            self.logger.info("登录成功")
            return True
        except TimeoutException:
            # self.take_screenshot("login_timeout")
            # self.logger.warning("登录状态验证失败，继续执行后续操作")
            return False
    def verify_logout_result(self):
        """验证退出登录结果"""
        try:
            WebDriverWait(self.driver, 2).until(
                lambda d: "/login" in d.current_url,
                message="登录后页面跳转超时"
            )
            self.logger.info("退出登录成功")
            return True
        except TimeoutException:
            # self.take_screenshot("login_timeout")
            self.logger.error("退出登录失败")
            return False

    def wait_for_login_form(self):
        self.wait_for_form_load('login_page_module', 'username')

    def S01_login_out(self):
        self.click('common_elements', 'login_out')
        self.verify_logout_result()

